package com.imis.base.util;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * SendSmsUtil<br>
 * 短信服务工具类
 * </p>
 *
 * @author XinLau
 * @version 1.0
 * @since 2020年04月18日 11:58
 */
@Slf4j
public class SendSmsUtil {

    /**
     * 短信模板变量对应的实际值
     */
    public static class TemplateParam {
        /**
         * 参数名
         */
        @Setter
        @Getter
        private String[] paramName;
        /**
         * 参数值
         */
        @Setter
        @Getter
        private String[] paramValue;

        /**
         * 构造函数
         *
         * @param paramName
         * @param paramValue
         */
        public TemplateParam(String[] paramName, String[] paramValue) {
            this.paramName = paramName;
            this.paramValue = paramValue;
        }

        /**
         * toString
         *
         * @return
         */
        @Override
        public String toString() {
            if (paramName.length != paramValue.length) {
                log.debug("参数名数组的长度跟参数值数组的长度不一样长");
                throw new RuntimeException("参数数量异常，请核对参数");
            }
            StringBuilder stringBuilder = new StringBuilder().append('{');
            for (int i = 0; i < paramValue.length; i++) {
                stringBuilder.append('\"').append(paramName[i]).append('\"')
                        .append(':').append('\"').append(paramValue[i]).append('\"');
            }
            stringBuilder.append('}');
            log.debug(stringBuilder.toString());
            return stringBuilder.toString();
        }
    }

    /**
     * 地区编号
     */
    private static final String REGION_ID = "cn-hangzhou";
    /**
     * 主账号AccessKey的ID。
     */
    @Setter
    @Getter
    private static String accessKeyId;
    /**
     * 秘钥
     */
    @Setter
    @Getter
    private static String accessKeySecret;

    /**
     * 参数验证
     *
     * @param templateParam - 短信模板变量对应的实际值
     * @param sendSmsEnum   - 短信模板信息
     * @return null -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/4/18 14:33
     */
    private static void validateParam(TemplateParam templateParam, SendSmsEnum sendSmsEnum) {
        String keys = sendSmsEnum.getKeys();
        String[] keyArr = keys.split(",");
        String[] paramName = templateParam.getParamName();
        if (paramName.length != keyArr.length) {
            log.debug("参数名数组的长度跟阿里短信模板枚举Kye的长度不一样长");
            throw new RuntimeException("模板参数数量异常，请核对参数");
        }
        for (int i = 0; i < keyArr.length; i++) {
            if (keyArr[i] != paramName[i]) {
                log.debug("参数名数组的第 {} 个参数跟阿里短信模板枚举的Kye不一样", i);
                throw new RuntimeException("参数名称异常，请核对参数");
            }
        }
    }

    /**
     * 发送短信
     *
     * @param sendSmsEnum   - 短信模板信息
     * @param phoneNumbers  - 接收短信的手机号码
     * @param templateParam - 短信模板变量对应的实际值
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/4/18 14:09
     */
    public static CommonResponse doSendSms(SendSmsEnum sendSmsEnum, String phoneNumbers, TemplateParam templateParam) {
//        1.验证参数
        validateParam(templateParam, sendSmsEnum);
//        2.初始化默认配置文件
        DefaultProfile profile = DefaultProfile.getProfile(REGION_ID, accessKeyId, accessKeySecret);
//        3.开启客户端
        IAcsClient client = new DefaultAcsClient(profile);
//        4.设置请求参数
        CommonRequest request = new CommonRequest();
//        请求方式
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
//        版本
        request.setVersion("2017-05-25");
//        系统规定参数。取值：SendSms。
        request.setAction("SendSms");
//        地区编号
        request.putQueryParameter("RegionId", REGION_ID);
//        接收短信的手机号码。支持对多个手机号码发送短信，手机号码之间以英文逗号（,）分隔。上限为1000个手机号码。批量调用相对于单条调用及时性稍有延迟。
        request.putQueryParameter("PhoneNumbers", phoneNumbers);
//        短信签名名称。请在控制台签名管理页面签名名称一列查看。
        request.putQueryParameter("SignName", sendSmsEnum.getSignName());
//        短信模板ID。请在控制台模板管理页面模板CODE一列查看。
        request.putQueryParameter("TemplateCode", sendSmsEnum.getTemplateCode());
//        短信模板变量对应的实际值，JSON格式。
        request.putQueryParameter("TemplateParam", templateParam.toString());
//        上行短信扩展码，无特殊需要此字段的用户请忽略此字段。
        request.putQueryParameter("SmsUpExtendCode", "90999");
//        外部流水扩展字段
        request.putQueryParameter("OutId", "ZZDZ");
        CommonResponse commonResponse = new CommonResponse();
        try {
//            5.发起请求
            commonResponse = client.getCommonResponse(request);
        } catch (ClientException e) {
            log.debug(e.getMessage());
        } catch (RuntimeException e) {
            log.debug(e.getMessage());
        }
        return commonResponse;
    }

}
